#ifndef PILE_H
#define PILE_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define INIT_CAPACITE 		1500			// Le nombre d'élement maximal au début
#define COEF_ALLOC 		3			// Le coéficient d'allocation mémoire
#define INIT_CAPACITE_CONTEXTE	100			// Taille initiale du tableau
#define COEF_ALLOC_CONTEXTE	3			// Coef d'allocation mémoire pour le tableau de contexte

struct element
{
	char nom[128];					// Son nom
	char valeur[256];				// Sa valeur
	int typeIdentificateur;				// le type de l'identificateur (const reel, var integer)
	int typeLiteral;				// Type: integer, reel, char ...
	char localisation[128];				// Dans quel fonction il est
};

struct contexte
{
	struct element **base;				// Stock une base
	int deplacement;				// Stock le déplacement actuel de la base
	char localisation[128];				// Stock sa localisation
};

struct pile
{
	int capaciteMax;				// La capacité maximale de la pile
	struct element **base;				// Tableau de pointeur sur un élément
	int deplacement;				// Le déplacement par rapport à la base
	int sommetPile;
	int flag;					// Flag de la pile
	struct element **origine;

	struct contexte **area;				// Tableau de contexte empilé
	int nContexte;					// Taille du tableau de contexte
	int capaciteMaxContexte;			// Capacité maximal

	struct contexte *saveBase;			// Sauvegarde du dernier contexte retiré
	int flagPassageReference;			// Flag pour savoir si la variable est passée par référence
};

/*Constructeur*/
struct pile* constrPile();
struct element* constrElement(char Nom[128], char Valeur[128], int TypeI, int typeL, char Localisation[128]);

/*Destructeur*/
void nettoyerPile(struct pile *p);

/*Empiler et dépiler*/
void empiler(struct pile *p, char Nom[128], char Valeur[128], int TypeI, int typeL, char Localisation[128]);
struct element* depiler(struct pile *p);

/*Gestion des bases (fonctions et procédures)*/
void setBase(struct pile *p, int deplacement);
void releaseBase(struct pile *p, int deplacement);

int estPresent(struct pile *p, char nom[128], char emplacement[128]);

/*Affichage*/
void affichagePile(struct pile *p);		// Juste la base actuelle
void affichagePile2(struct pile *p);		// Toute la pile
void affichageContexte(struct pile *p);		// Contextes sauvegardés
#endif
